import React, { FC, useMemo, useState, useEffect } from 'react'
import { View, Text } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { Icon } from '@antmjs/vantui'
import './index.less'

export interface CustomNavBarProps {
  /** 导航栏标题 */
  title: string;
  /** 左侧图标的 Vant Icon 名称, 默认为 'arrow-left' */
  leftIconName?: string;
  /** 是否显示左侧图标，默认为 true */
  showLeftIcon?: boolean;
  /** 点击左侧图标的事件, 如果不提供，默认是返回上一页 */
  onLeftIconClick?: () => void;
  /** 导航栏背景, 可以是颜色值或渐变色 */
  background?: string;
  /** 标题和图标的颜色 */
  color?: string;
  /** 子元素，会显示在导航栏标题下方 */
  children?: React.ReactNode;
}

const CustomNavBar: FC<CustomNavBarProps> = (props) => {
  const {
    title,
    leftIconName = 'arrow-left',
    showLeftIcon = true,
    onLeftIconClick,
    background = 'linear-gradient(180deg, #8BBEFF 20%, #ACE0FF 100%)',
    color = '#FFFFFF',
    children,
  } = props;

  // 使用 State 来存储计算出的总高度
  const [totalHeight, setTotalHeight] = useState(0);

  // 动态计算基础高度
  const { statusBarHeight, navBarContentHeight } = useMemo(() => {
    try {
      const systemInfo = Taro.getSystemInfoSync();
      const menuButtonInfo = Taro.getMenuButtonBoundingClientRect();
      const sh = systemInfo.statusBarHeight || 0;
      // (胶囊上边距 - 状态栏高度) * 2 + 胶囊高度 = 导航栏内容高度
      const nbh = (menuButtonInfo.top - sh) * 2 + menuButtonInfo.height;
      return {
        statusBarHeight: sh,
        navBarContentHeight: nbh,
      };
    } catch (e) {
      // 兼容H5等环境的异常
      return { statusBarHeight: 20, navBarContentHeight: 44 }
    }
  }, []);

  // 使用 useEffect 在组件渲染后计算完整高度（包括children）
  useEffect(() => {
    // Taro React Hooks中，不需要 .in(this.$scope)
    const query = Taro.createSelectorQuery();
    query.select('.custom-nav-bar-wrapper').boundingClientRect(rect => {
      if (rect) {
        setTotalHeight(rect.height);
      }
    }).exec();
  }, [children]); // 当 children 内容变化时，重新计算高度

  const handleLeftClick = () => {
    if (onLeftIconClick) {
      onLeftIconClick();
    } else {
      Taro.navigateBack();
    }
  };

  return (
    // 使用 React.Fragment 包裹，因为它会渲染多个顶级元素
    <>
      {/*
        第一部分：固定的导航栏本体
        它会脱离文档流，浮在页面最上方。
      */}
      <View
        className='custom-nav-bar-wrapper'
        style={{
          background,
          paddingTop: `${statusBarHeight}px`,
        }}
      >
        {/* 标题栏区域 */}
        <View
          className='nav-bar-content'
          style={{ height: `${navBarContentHeight}px` }}
        >
          <View className='nav-bar-left' onClick={handleLeftClick}>
            {showLeftIcon && <Icon name={leftIconName} size='24PX' color={color} />}
          </View>
          <Text className='nav-bar-title' style={{ color }}>{title}</Text>
          <View className='nav-bar-right'></View>
        </View>

        {/* 下方自定义内容区域 */}
        {children && (
          <View className='nav-bar-extra-content'>
            {children}
          </View>
        )}
      </View>

      {/*
        第二部分：等高的、用于占位的透明元素
        这个 View 在正常的文档流里，会把下面的内容推下去，
        从而完美地解决了需要在外部添加 paddingTop 的问题。
      */}
      <View
        className='nav-bar-placeholder'
        style={{ height: `${totalHeight}px` }}
      />
    </>
  );
};

export default CustomNavBar;
